<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Genivia - The WS-Addressing Plugin</title>
<link href="genivia_tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="genivia_content.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="top">
 <div id="titlearea">
  <table height="72px" width="100%" cellspacing="0" cellpadding="0">
   <tbody>
    <tr>
     <td width="10%">&nbsp;</td>
     <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td>
     <td class="tab_home"><a href="https://www.genivia.com">Home</a></td>
     <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td>
     <td>
      <div style="float: right; font-size: 18px; font-weight: bold;">The WS-Addressing Plugin</div>
      <br>
      <div style="float: right; font-size: 10px;">updated Thu Nov 19 2020 by Robert van Engelen</div>
     </td>
     <td width="10%">&nbsp;</td>
    </tr>
   </tbody>
  </table>
 </div>
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li class="current"><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">The WS-Addressing Plugin </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#wsa_1">WS-Addressing Setup</a></li>
<li class="level1"><a href="#wsa_2">Client-side Usage</a><ul><li class="level2"><a href="#wsa_2_1">Constructing WS-Addressing Information Headers</a></li>
<li class="level2"><a href="#wsa_2_2">Information Headers for Relaying Server Responses</a></li>
<li class="level2"><a href="#wsa_2_3">Information Headers for Relaying Server Faults</a></li>
<li class="level2"><a href="#wsa_2_4">Error Handling</a></li>
<li class="level2"><a href="#wsa_2_5">Combining WS-Addressing with WS-Security</a></li>
</ul>
</li>
<li class="level1"><a href="#wsa_3">Server-side Usage</a></li>
<li class="level1"><a href="#wsa_4">HTTPS Server-side Usage</a></li>
<li class="level1"><a href="#wsa_5">Implementing a Server for Handling ReplyTo Response Messages</a></li>
<li class="level1"><a href="#wsa_6">Implementing a Server for Handling FaultTo Fault Messages</a></li>
</ul>
</div>
<div class="textblock"><h1><a class="anchor" id="wsa_1"></a>
WS-Addressing Setup</h1>
<p>The material in this section relates to the WS-Addressing specification.</p>
<p>To use the wsa plugin:</p><ol type="1">
<li>Run wsdl2h -t typemap.dat on a WSDL of a service that requires WS-Addressing headers. The typemap.dat file included in the gSOAP package is used to recognize and translate Addressing header blocks.</li>
<li>Run soapcpp2 -a on the header file produced by wsdl2h. To enable addressing-based service operation selection, you MUST use soapcpp2 option -a. This allows the service to dispatch methods based on the WS-Addressing action information header value (when the wsa plugin is registered).</li>
<li>(Re-)compile and link stdsoap2.c/pp or libgsoap, (dom.c/pp when needed), <a class="el" href="wsaapi_8c.html">wsaapi.c</a> and the soapcpp2-generated source files.</li>
<li>Use the wsa plugin API functions described below.</li>
</ol>
<p>An example wsa client/server application can be found in <code>gsoap/samples/wsa</code>.</p>
<p>A gSOAP service definitions header file with a <code>#import "wsa.h"</code> to support WS-Addressing is automatically generated by wsdl2h for a set of WSDLs that use WS-Addressing. The wsdl2h-generated header file should be further processed by soapcpp2 to generate the binding code. The <a class="el" href="wsaapi_8h.html">wsaapi.h</a> and <a class="el" href="wsaapi_8c.html">wsaapi.c</a> implement the WS-Addressing API described in this document.</p>
<p>A wsdl2h-generated service definitions header file might include the following imports:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;soap12.h&quot;</span></div><div class="line"><span class="preprocessor">#import &quot;wsa.h&quot;</span> <span class="comment">// or wsa3.h (2003/03), wsa4.h (2004/03), wsa5.h (2005/03)</span></div></div><!-- fragment --><p>The wsa.h header file is imported from import/wsa.h when soapcpp2 is run on this file. The wsa.h import can be manually added to enable WS-Addressing when needed. The gSOAP service definitions header file is processed with soapcpp2 to generate the client-side and/or server-side binding code.</p>
<p>Note that the wsa.h, wsa3.h, wsa4.h, and <a class="el" href="wsa5_8h.html">wsa5.h</a> header files are located in the import directory of the gSOAP package. These files define the WS-Addressing information header elements and types. The soap12.h header file enables SOAP 1.2 messaging.</p>
<p>For developers: the WS-Addressing header blocks in wsa.h (and others) were generated from the WS-Addressing schema with the wsdl2h tool and WS/WS-typemap.dat as follows: </p><pre class="fragment">wsdl2h -cegy -o wsa.h -t WS/WS-typemap.dat WS/WS-Addressing.xsd
</pre><p>Refer to wsa.h for more details.</p>
<h1><a class="anchor" id="wsa_2"></a>
Client-side Usage</h1>
<h2><a class="anchor" id="wsa_2_1"></a>
Constructing WS-Addressing Information Headers</h2>
<p>To associate WS-Addressing information headers with service operations, the SOAP Header struct <code><a class="el" href="struct_s_o_a_p___e_n_v_____header.html" title="Added. ">SOAP_ENV__Header</a></code> must have been defined and for each service operation that uses WS-Addressing method-header-part directives should be used in the gSOAP service definitions header file as follows:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;wsa.h&quot;</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__MessageID</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__RelatesTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__From</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__ReplyTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__FaultTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__To</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: example wsa__Action</span></div><div class="line"><span class="comment">//gsoap ns service method-action: example urn:example/examplePort/example</span></div><div class="line"><span class="keywordtype">int</span> ns__example(<span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out);</div></div><!-- fragment --><p>Note that the use of wsa versions determines the wsa prefix, e.g. use <code>wsa5</code> for the latest WS-Addressing as in <code>wsa5__MessageID</code>.</p>
<p>In the client-side code, the WS-Addressing information headers are set with <code>soap_wsa_request</code> by passing an optional message UUID string, a mandatory destination address URI string, and a mandatory request action URI string. The wsa plugin should be registered with the current soap struct context. An optional source address information header can be added with <code>soap_wsa_add_From</code> (must be invoked after the <code>soap_wsa_request</code> call).</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wsaapi_8h.html">wsaapi.h</a>&quot;</span></div><div class="line">soap_register_plugin(soap, <a class="code" href="wsaapi_8h.html#aa013e3760b97c2efcc71d29b57394501">soap_wsa</a>);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a3cbfe63b812df21c0bc2c8a129a1dc99">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction))</div><div class="line"> || <a class="code" href="wsaapi_8h.html#a173c7beac1825c49f5d3b446ccdbc6b8">soap_wsa_add_From</a>(soap, FromAddress)) <span class="comment">// optional: add a &#39;From&#39; address</span></div><div class="line">  ... <span class="comment">// error: out of memory</span></div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))</div><div class="line">  soap_print_fault(soap, stderr); <span class="comment">// an error occurred</span></div><div class="line"><span class="keywordflow">else</span></div><div class="line">  <span class="comment">// process the response </span></div></div><!-- fragment --><p>To generate a UUID for the RequestMessageID, use:</p>
<div class="fragment"><div class="line"><span class="keyword">const</span> <span class="keywordtype">char</span> *RequestMessageID = <a class="code" href="wsaapi_8h.html#ac2b81c42093fc9fcadcf86e7d801e03b">soap_wsa_rand_uuid</a>(soap);</div></div><!-- fragment --><h2><a class="anchor" id="wsa_2_2"></a>
Information Headers for Relaying Server Responses</h2>
<p>To relay the response to another destination, the WS-Addressing ReplyTo information header is added with <code>soap_wsa_add_ReplyTo</code> by passing a reply address URI string. The service returns "HTTP 202 ACCEPTED" to the client when the response message relay was successful.</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wsaapi_8h.html">wsaapi.h</a>&quot;</span></div><div class="line">soap_register_plugin(soap, <a class="code" href="wsaapi_8h.html#aa013e3760b97c2efcc71d29b57394501">soap_wsa</a>);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a3cbfe63b812df21c0bc2c8a129a1dc99">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction)</div><div class="line"> || <a class="code" href="wsaapi_8h.html#a173c7beac1825c49f5d3b446ccdbc6b8">soap_wsa_add_From</a>(soap, FromAddress) <span class="comment">// optional: add a &#39;From&#39; address</span></div><div class="line"> || <a class="code" href="wsaapi_8h.html#a8b4871953a687b6f360b04c4bddeb49c">soap_wsa_add_ReplyTo</a>(soap, ReplyToAddress))</div><div class="line">  ... <span class="comment">// error: out of memory</span></div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span></div><div class="line">    printf(<span class="stringliteral">&quot;Request was accepted and results were forwarded\n&quot;</span>);</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    soap_print_fault(soap, stderr); <span class="comment">// an error occurred</span></div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">  <span class="comment">// unexpected OK: for some reason the response was not relayed</span></div></div><!-- fragment --><p>Note: the response message will be relayed when the From address is absent or different than the ReplyTo address</p>
<h2><a class="anchor" id="wsa_2_3"></a>
Information Headers for Relaying Server Faults</h2>
<p>To relay a server fault message to another destination, the WS-Addressing FaultTo information header is added with <code>soap_wsa_add_FaultTo</code> by passing a relay address URI string. The service returns "HTTP 202 ACCEPTED" to the client when the fault was relayed.</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wsaapi_8h.html">wsaapi.h</a>&quot;</span></div><div class="line">soap_register_plugin(soap, <a class="code" href="wsaapi_8h.html#aa013e3760b97c2efcc71d29b57394501">soap_wsa</a>);</div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a3cbfe63b812df21c0bc2c8a129a1dc99">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction)</div><div class="line"> || <a class="code" href="wsaapi_8h.html#a173c7beac1825c49f5d3b446ccdbc6b8">soap_wsa_add_From</a>(soap, FromAddress) <span class="comment">// optional: add a &#39;From&#39; address</span></div><div class="line"> || <a class="code" href="wsaapi_8h.html#afc91d81e9eec6b9bc39efbd5e715a18a">soap_wsa_add_FaultTo</a>(soap, FaultToAddress))</div><div class="line">  ... <span class="comment">// error: out of memory</span></div><div class="line"></div><div class="line"><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span></div><div class="line">    printf(<span class="stringliteral">&quot;A fault occurred and the fault details were forwarded\n&quot;</span>);</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    soap_print_fault(soap, stderr); <span class="comment">// a connection error occurred</span></div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">  ... <span class="comment">// process response </span></div></div><!-- fragment --><p>Note that the call can still return a fault, such as a connection error when the service is not responding. In addition to the fault relay, the responses can be relayed with <code>soap_wsa_add_ReplyTo</code>.</p>
<h2><a class="anchor" id="wsa_2_4"></a>
Error Handling</h2>
<p>SOAP and HTTP errors set the soap-&gt;error attribute, as shown in this example:</p>
<div class="fragment"><div class="line"><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (soap-&gt;error == 202) <span class="comment">// HTTP ACCEPTED</span></div><div class="line">    printf(<span class="stringliteral">&quot;A fault occurred and the fault details were forwarded\n&quot;</span>);</div><div class="line">  <span class="keywordflow">else</span></div><div class="line">    soap_print_fault(soap, stderr); <span class="comment">// a connection error occurred</span></div><div class="line">}</div><div class="line"><span class="keywordflow">else</span></div><div class="line">  ... <span class="comment">// process response </span></div></div><!-- fragment --><p>When a WS-Addressing error occurred, the wsa error code is stored in the SOAP Fault Subcode field. This information can be retrieved with:</p>
<div class="fragment"><div class="line">wsa__FaultSubcodeValues fault;</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a4a67f22e5cb3659b0198c61a71f99fb0">soap_wsa_check_fault</a>(soap, &amp;fault))</div><div class="line">{</div><div class="line">  <span class="keywordflow">switch</span> (fault)</div><div class="line">  {</div><div class="line">    <span class="keywordflow">case</span> wsa__InvalidMessageInformationHeader: ...</div><div class="line">    <span class="keywordflow">case</span> wsa__MessageInformationHeaderRequired: ...</div><div class="line">    <span class="keywordflow">case</span> wsa__DestinationUreachable: ...</div><div class="line">    <span class="keywordflow">case</span> wsa__ActionNotSupported: ...</div><div class="line">    <span class="keywordflow">case</span> wsa__EndpointUnavailable: ...</div><div class="line">  }</div><div class="line">}</div></div><!-- fragment --><p>When using <a class="el" href="wsa5_8h.html">wsa5.h</a>, please refer to the standards and fault codes for this implementation. For the <a class="el" href="wsa5_8h.html">wsa5.h</a> 2005/03 standard, several faults have an additional parameter (SOAP Fault detail):</p>
<div class="fragment"><div class="line"><a class="code" href="wsa5_8h.html#ae5ccb3ea0378299be007d022f1d3ef5a">wsa5__FaultCodesType</a> fault;</div><div class="line"><span class="keywordtype">char</span> *info;</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a4a67f22e5cb3659b0198c61a71f99fb0">soap_wsa_check_fault</a>(soap, &amp;fault, &amp;info))</div><div class="line">{</div><div class="line">  <span class="keywordflow">switch</span> (fault)</div><div class="line">  {</div><div class="line">    <span class="keywordflow">case</span> <a class="code" href="wsa5_8h.html#ae5ccb3ea0378299be007d022f1d3ef5aa9e6c5b22cdf5c37f9c8fed89725cfee3">wsa5__InvalidAddressingHeader</a>:</div><div class="line">      <span class="keywordflow">if</span> (info)</div><div class="line">        printf(<span class="stringliteral">&quot;The invalid addressing header element is %s\n&quot;</span>, info);</div><div class="line">    ...</div><div class="line">  }</div><div class="line">}</div></div><!-- fragment --><h2><a class="anchor" id="wsa_2_5"></a>
Combining WS-Addressing with WS-Security</h2>
<p>WS-Security can be combined with WS-Addressing. To sign WS-Addressing header blocks, use the <code>soap_wsse_set_wsu_id</code> WSSE-plugin call to set the wsu:Id attribute and signing of these attributed elements. For example, suppose we use WS-Addressing 2005 headers (which are activated with an <code>#import "wsa5.h"</code> in the header file for soapcpp2):</p>
<div class="fragment"><div class="line"><span class="preprocessor">#include &quot;<a class="code" href="wsaapi_8h.html">wsaapi.h</a>&quot;</span></div><div class="line"><span class="preprocessor">#include &quot;wsseapi.h&quot;</span></div><div class="line">soap_register_plugin(soap, <a class="code" href="wsaapi_8h.html#aa013e3760b97c2efcc71d29b57394501">soap_wsa</a>);</div><div class="line">soap_register_plugin(soap, soap_wsse);</div><div class="line"></div><div class="line">soap_wsse_set_wsu_id(soap, <span class="stringliteral">&quot;wsa5:From wsa5:To wsa5:ReplyTo wsa5:FaultTo wsa5:Action wsa5:MessageID&quot;</span>);</div><div class="line"><span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a3cbfe63b812df21c0bc2c8a129a1dc99">soap_wsa_request</a>(soap, RequestMessageID, ToAddress, RequestAction)</div><div class="line"> || <a class="code" href="wsaapi_8h.html#a173c7beac1825c49f5d3b446ccdbc6b8">soap_wsa_add_From</a>(soap, FromAddress) <span class="comment">// optional: add a &#39;From&#39; address</span></div><div class="line"> || <a class="code" href="wsaapi_8h.html#afc91d81e9eec6b9bc39efbd5e715a18a">soap_wsa_add_FaultTo</a>(soap, FaultToAddress))</div><div class="line">  ... <span class="comment">// error: out of memory</span></div><div class="line"><span class="keywordflow">if</span> (soap_call_ns__example(soap, ToAddress, NULL, ...))</div><div class="line">  ... <span class="comment">// error</span></div></div><!-- fragment --><p>If your are using WS-Addressing 2004 (which is activated with an <code>#import "wsa.h"</code> in the header file for soapcpp2) then change one line:</p>
<div class="fragment"><div class="line">soap_wsse_set_wsu_id(soap, <span class="stringliteral">&quot;wsa:From wsa:To wsa:ReplyTo wsa:FaultTo wsa:Action wsa:MessageID&quot;</span>);</div></div><!-- fragment --><p>Note: <code>soap_wsse_set_wsu_id</code> should only be set once. Each new call overrides the previous.</p>
<p>For more details on WS-Security, please see the <a href="../../wsse/html/index.html">WS-Security plugin documentation</a>.</p>
<h1><a class="anchor" id="wsa_3"></a>
Server-side Usage</h1>
<p>The wsa plugin should be registered with:</p>
<div class="fragment"><div class="line">soap_register_plugin(soap, <a class="code" href="wsaapi_8h.html#aa013e3760b97c2efcc71d29b57394501">soap_wsa</a>);</div></div><!-- fragment --><p>Once the plugin is registered, the <code>soap_bind</code>, <code>soap_accept</code>, and <code>soap_serve</code> functions can be called to process requests and semi-automatically handle the WS-Addressing header blocks.</p>
<p>Important: to dispatch service operations based on the WS-Addressing wsa:Action information header, you must use soapcpp2 option <code>-a</code>. The generates a new dispatcher (in soapServer.c) based on the action value.</p>
<p>A service operation implementation should use <code>soap_wsa_check</code> at the start of its execution to verify the validity of the WS-Addressing information headers in the SOAP request message. To allow response message to be automatically relayed based on the ReplyTo information header, the service operation should return <code>soap_wsa_reply</code> with an optional message UUID string and a mandatory response action string. The response action string is documented in the wsdl2h-generated .h file for this service operation.</p>
<p>For example:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> ns__example(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out)</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a35f9b1c46ea38b271b8d26bf8b051640">soap_wsa_check</a>(soap))</div><div class="line">    <span class="keywordflow">return</span> soap-&gt;error;</div><div class="line">  <span class="comment">// ... service logic</span></div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a54fda97d2591acd5e2385cc110a50b30">soap_wsa_reply</a>(soap, ResponseMessageID, ResponseAction);</div><div class="line">}</div></div><!-- fragment --><p>To return a SOAP fault that is automatically relayed to a fault service based on the FaultTo information header, the <code>soap_wsa_sender_fault</code>, <code>soap_wsa_receiver_fault</code>, <code>soap_wsa_sender_fault_subcode</code>, and <code>soap_wsa_receiver_fault_subcode</code> functions should be used instead of the usual <code>soap_sender_fault</code>, <code>soap_receiver_fault</code>, <code>soap_sender_fault_subcode</code>, and <code>soap_receiver_fault_subcode</code>, respectively:</p>
<p>In case a Action must be associated with a SOAP Fault, use the <code>soap_wsa_sender_fault_subcode_action</code> and <code>soap_wsa_receiver_fault_subcode_action</code> functions to set the WS-Addressing Action (and HTTP SOAP Action header as well).</p>
<p>For example, the following service operation illustrates the use of <code>soap_wsa_check</code> to verify and process WS-Addressing header blocks and <code>soap_wsa_reply</code> to enable responses to be relayed as per ReplyTo address in the WS-Addressing header:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> ns__example(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *in, <span class="keyword">struct</span> ns__exampleResponse *out)</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a35f9b1c46ea38b271b8d26bf8b051640">soap_wsa_check</a>(soap))</div><div class="line">    <span class="keywordflow">return</span> soap-&gt;error;</div><div class="line">  <span class="comment">// ... service logic</span></div><div class="line">  <span class="comment">// ... an error occurred, need to return fault possibly to fault service:</span></div><div class="line">    <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a1e3eb7af78b1de680ac5352605afcd00">soap_wsa_sender_fault</a>(soap, <span class="stringliteral">&quot;Exception in service operation&quot;</span>, NULL);</div><div class="line">  <span class="comment">// ... normal execution continues</span></div><div class="line">  <span class="keywordflow">return</span> <a class="code" href="wsaapi_8h.html#a54fda97d2591acd5e2385cc110a50b30">soap_wsa_reply</a>(soap, ResponseMessageID, ResponseAction);</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="wsa_4"></a>
HTTPS Server-side Usage</h1>
<p>To enable HTTPS (SSL/TSL) servers, compile the sources with -DWITH_OPENSSL (and link with libgsoapssl, libssl, and libcrypto). Because WS-Addressing may relay messages over HTTPS as a sender (client), you must initialize the SSL context for server and client uses. Therefore, the context must have access to all the certificates need to verify the authenticity of the ReplyTo and FaultTo HTTPS servers. To do so, use the following SSL initialization before <code>soap_bind</code>:</p>
<div class="fragment"><div class="line"><span class="keyword">struct </span>soap *soap = soap_new();</div><div class="line"><span class="keywordflow">if</span> (soap_ssl_server_context(soap,</div><div class="line">  SOAP_SSL_DEFAULT,</div><div class="line">  <span class="stringliteral">&quot;server.pem&quot;</span>, <span class="comment">// the keyfile (server should authenticate)</span></div><div class="line">  <span class="stringliteral">&quot;password&quot;</span>,   <span class="comment">// password to read the key file</span></div><div class="line">  <span class="stringliteral">&quot;cacert.pem&quot;</span>, <span class="comment">// cacert file to store trusted certificates (role as client)</span></div><div class="line">  NULL,         <span class="comment">// optional capath</span></div><div class="line">  NULL,         <span class="comment">// DH file name or DH param key len bits, when NULL use RSA</span></div><div class="line">  NULL,         <span class="comment">// file with random data to seed randomness</span></div><div class="line">  <span class="stringliteral">&quot;myserver&quot;</span>    <span class="comment">// unique server identification for SSL session cache</span></div><div class="line">))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">  ...</div><div class="line">}</div><div class="line">soap-&gt;bind_flags = SO_REUSEADDR;</div><div class="line"><span class="keywordflow">if</span> (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))</div><div class="line">{</div><div class="line">  soap_print_fault(soap, stderr);</div><div class="line">  ...</div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="wsa_5"></a>
Implementing a Server for Handling ReplyTo Response Messages</h1>
<p>To implement a separate server for handling relayed SOAP response messages based on the ReplyTo information header in the request message, the gSOAP header file should include a one-way service operation for the response message. These one-way response service operations are automatically generated with wsdl2h option <code>-b</code>.</p>
<p>For example, suppose a service operation returns an exampleResponse message. We declare the one-way exampleResponse operation as follows:</p>
<div class="fragment"><div class="line"><span class="preprocessor">#import &quot;wsa.h&quot;</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__MessageID</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__RelatesTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__From</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__ReplyTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__FaultTo</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__To</span></div><div class="line"><span class="comment">//gsoap ns service method-header-part: exampleResult wsa__Action</span></div><div class="line"><span class="comment">//gsoap ns service method-action: exampleResult urn:example/examplePort/exampleResponse</span></div><div class="line"><span class="keywordtype">int</span> ns__exampleResponse(<span class="keywordtype">char</span> *out, <span class="keywordtype">void</span>);</div></div><!-- fragment --><p>Note that the action information is important, because it is used by the service dispatcher (assuming soapcpp2 option <code>-a</code> is used).</p>
<p>The implementation in the server code uses <a class="el" href="wsaapi_8c.html#acea5440a6af758896cdd73be65d275fc" title="Checks the presence and validity of WS-Addressing information headers. ">soap_wsa_check()</a> to check the presense and validity of the WS-Addressing information header in the message. The <code>soap_send_empty_response</code> function should be used to return an acknowledgment HTTP header with "HTTP 202 ACCEPTED" to the sender:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> ns__exampleResponse(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *out)</div><div class="line">{</div><div class="line">  <span class="keywordflow">if</span> (<a class="code" href="wsaapi_8h.html#a35f9b1c46ea38b271b8d26bf8b051640">soap_wsa_check</a>(soap))</div><div class="line">    <span class="keywordflow">return</span> soap_send_empty_response(soap, 500); <span class="comment">// HTTP 500 Internal Server Error</span></div><div class="line">  <span class="comment">// ... service logic</span></div><div class="line">  <span class="keywordflow">return</span> soap_send_empty_response(soap, SOAP_OK); <span class="comment">// HTTP 202 ACCEPTED</span></div><div class="line">}</div></div><!-- fragment --><h1><a class="anchor" id="wsa_6"></a>
Implementing a Server for Handling FaultTo Fault Messages</h1>
<p>To implement a separate server for handling relayed SOAP fault messages based on the FaultTo information header in the request message, the gSOAP header file for soapcpp2 should include a SOAP fault service operation. This operation accepts fault messages that are relayed by other services.</p>
<p>Basically, we use a trick to generate the SOAP-ENV:Fault struct via a one-way service operation. This allows us both to implement a one-way service operation that accepts faults and to automatically generate the fault struct for fault data storage and manipulation.</p>
<p>The fault operation in the WS-Addressing files (<a class="el" href="wsa5_8h.html">wsa5.h</a> etc.) is declared as follows (here shown for the 2004/08 standard):</p>
<div class="fragment"><div class="line"><span class="comment">//gsoap SOAP_ENV service method-action: Fault http://schemas.xmlsoap.org/ws/2004/08/addressing/fault</span></div><div class="line"><span class="keywordtype">int</span> <a class="code" href="wsa5_8h.html#af1f0af3d70354401b6969aa0b689a5dc">SOAP_ENV__Fault</a></div><div class="line">(</div><div class="line">        _QName                       faultcode,             <span class="comment">// SOAP 1.1</span></div><div class="line">        <span class="keywordtype">char</span>                        *faultstring,           <span class="comment">// SOAP 1.1</span></div><div class="line">        <span class="keywordtype">char</span>                        *faultactor,            <span class="comment">// SOAP 1.1</span></div><div class="line">        <span class="keyword">struct</span> SOAP_ENV__Detail     *detail,                <span class="comment">// SOAP 1.1</span></div><div class="line">        <span class="keyword">struct</span> SOAP_ENV__Code       *SOAP_ENV__Code,        <span class="comment">// SOAP 1.2</span></div><div class="line">        <span class="keyword">struct</span> SOAP_ENV__Reason     *SOAP_ENV__Reason,      <span class="comment">// SOAP 1.2</span></div><div class="line">        <span class="keywordtype">char</span>                        *SOAP_ENV__Node,        <span class="comment">// SOAP 1.2</span></div><div class="line">        <span class="keywordtype">char</span>                        *SOAP_ENV__Role,        <span class="comment">// SOAP 1.2</span></div><div class="line">        <span class="keyword">struct</span> SOAP_ENV__Detail     *SOAP_ENV__Detail,      <span class="comment">// SOAP 1.2</span></div><div class="line">        <span class="keywordtype">void</span></div><div class="line">);</div></div><!-- fragment --><p>Because each service operation has a struct to hold its input parameters, we automatically generate the (original) <code>SOAP_ENV__Fault</code> struct on the fly!</p>
<p>It is important to associate the wsa fault action with this operation as shown above.</p>
<p>The implementation of the Fault service operation in your server code should be similar to:</p>
<div class="fragment"><div class="line"><span class="keywordtype">int</span> <a class="code" href="wsa5_8h.html#af1f0af3d70354401b6969aa0b689a5dc">SOAP_ENV__Fault</a>(<span class="keyword">struct</span> soap *soap, <span class="keywordtype">char</span> *faultcode, <span class="keywordtype">char</span> *faultstring, <span class="keywordtype">char</span> *faultactor, <span class="keyword">struct</span> SOAP_ENV__Detail *detail, <span class="keyword">struct</span> SOAP_ENV__Code *SOAP_ENV__Code, <span class="keyword">struct</span> SOAP_ENV__Reason *SOAP_ENV__Reason, <span class="keywordtype">char</span> *SOAP_ENV__Node, <span class="keywordtype">char</span> *SOAP_ENV__Role, <span class="keyword">struct</span> SOAP_ENV__Detail *SOAP_ENV__Detail)</div><div class="line">{ </div><div class="line">  ... = faultcode; <span class="comment">// SOAP 1.1 fault code string (QName)</span></div><div class="line">  ... = faultstring; <span class="comment">// SOAP 1.1 fault string</span></div><div class="line">  ... = faultactor; <span class="comment">// SOAP 1.1 fault actor string</span></div><div class="line">  ... = detail; <span class="comment">// SOAP 1.1 fault detail struct</span></div><div class="line">  ... = SOAP_ENV__Code; <span class="comment">// SOAP 1.2 fault code struct</span></div><div class="line">  ... = SOAP_ENV__Reason; <span class="comment">// SOAP 1.2 reason struct</span></div><div class="line">  ... = SOAP_ENV__Node; <span class="comment">// SOAP 1.2 node string</span></div><div class="line">  ... = SOAP_ENV__Role; <span class="comment">// SOAP 1.2 role string</span></div><div class="line">  ... = SOAP_ENV__Detail; <span class="comment">// SOAP 1.2 detail struct</span></div><div class="line">  <span class="keywordflow">return</span> SOAP_OK;</div><div class="line">}</div></div><!-- fragment --><p>Note that SOAP 1.1 or SOAP 1.2 parameters are set based on the 1.1/1.2 messaging requirements. </p>
</div></div><!-- contents -->
<hr class="footer">
<address class="footer">
Copyright (C) 2020, Robert van Engelen, Genivia Inc., All Rights Reserved.
</address>
<address class="footer"><small>
Converted on Thu Nov 19 2020 12:38:04 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address>
<br>
<div style="height: 246px; background: #DBDBDB;">
</body>
</html>
